package com.xin.di.uav.applet.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xin.di.uav.applet.mapper.CityReceivingInformationMapper;
import com.xin.di.uav.applet.mapper.ReceivingInformationMapper;
import com.xin.di.uav.applet.service.IReceivingInformationService;
import com.xin.di.uav.common.awt.JwtUtil;
import com.xin.di.uav.common.request.user.ReceivingInformationAddRequest;
import com.xin.di.uav.common.request.user.ReceivingInformationRequest;
import com.xin.di.uav.common.response.user.ReceivingInformationResponse;
import com.xin.di.uav.common.utils.BeanUtil;
import com.xin.di.uav.common.utils.MobileNumberValidatorUtil;
import com.xin.di.uav.common.utils.PhoneDesensitizationUtil;
import com.xin.di.uav.common.utils.PhoneEncoderUtil;
import com.xin.di.uav.user.entity.CityReceivingInformation;
import com.xin.di.uav.user.entity.ReceivingInformation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 收货信息表 服务实现类
 * </p>
 *
 * @author LTQ
 * @since 2023-04-04
 */
@Service
public class ReceivingInformationServiceImpl extends ServiceImpl<ReceivingInformationMapper, ReceivingInformation> implements IReceivingInformationService {

    @Autowired
    private ReceivingInformationMapper receivingInformationMapper;


    @Autowired
    private CityReceivingInformationMapper cityReceivingInformationMapper;

    @Autowired
    private IReceivingInformationService iReceivingInformationService;

    @Autowired
    private PhoneEncoderUtil phoneEncoderUtil;

    private final static String PHONE_VERIFY = "^1[0-9]{10}$";

    @Override
    @CacheEvict(value = "RESCUE::RECEIVING_INFORMATION", key = "#receivingInformationRequest.userId")
    public void add(ReceivingInformationRequest receivingInformationRequest) {
        String userId = JwtUtil.getUserId();
        Date date = new Date();
        ReceivingInformation receivingInformation = new ReceivingInformation();
        BeanUtils.copyProperties(receivingInformationRequest, receivingInformation);
        receivingInformation.setUserId(userId);
        receivingInformation.setUpdateTime(date);
        receivingInformation.setCreateTime(date);
        receivingInformationMapper.insert(receivingInformation);
    }

    @Override
    @CacheEvict(value = "RESCUE::RECEIVING_INFORMATION", key = "#receivingInformationRequest.userId")
    public void edit(ReceivingInformationRequest receivingInformationRequest) {
        String phoneNum = receivingInformationRequest.getPhoneNum();
        String phoneCode = receivingInformationRequest.getPhoneCode();
        this.checkPhone(phoneNum, phoneCode);
        String userId = JwtUtil.getUserId();
        Date date = new Date();
        ReceivingInformation receivingInformation = new ReceivingInformation();
        BeanUtils.copyProperties(receivingInformationRequest, receivingInformation);
        receivingInformation.setId(receivingInformationRequest.getId());
        receivingInformation.setUserId(userId);
        receivingInformation.setUpdateTime(date);
        receivingInformationMapper.updateById(receivingInformation);
    }

    private void checkPhone(String phoneNum, String phoneCode) {
        if (!MobileNumberValidatorUtil.isValidChineseMobileNumber(phoneNum) && !MobileNumberValidatorUtil.isValidChinesePhoneNumberWithNoExtensionNumber(phoneNum)) {
            throw new RuntimeException("手机号码或电话号码格式错误！");
        }
        if (!ObjectUtils.isEmpty(phoneCode)) {
            if (!MobileNumberValidatorUtil.isValidExtensionNumber(phoneCode)) {
                throw new RuntimeException("分机号格式错误！");
            }
        }
    }

    @Override
//    @CacheEvict(value = "CITY::RECEIVING_INFORMATION", key = "#receivingInformationRequest.userId")
    public void addAddress(ReceivingInformationAddRequest receivingInformationAddRequest) {
        String phoneNum = receivingInformationAddRequest.getPhoneNum();
        String phoneCode = receivingInformationAddRequest.getPhoneCode();
        this.checkPhone(phoneNum, phoneCode);
        String userId = JwtUtil.getUserId();
        Date date = new Date();
        CityReceivingInformation cityReceivingInformation = new CityReceivingInformation();
        BeanUtils.copyProperties(receivingInformationAddRequest, cityReceivingInformation);
        cityReceivingInformation.setUserId(userId);
        cityReceivingInformation.setUpdateTime(date);
        cityReceivingInformation.setCreateTime(date);
        iReceivingInformationService.insert(cityReceivingInformation);
    }

    @Override
//    @CacheEvict(value = "CITY::RECEIVING_INFORMATION", key = "#receivingInformationRequest.userId")
    public void editAddress(ReceivingInformationRequest receivingInformationRequest) {
        String id = receivingInformationRequest.getId();
        String userId = JwtUtil.getUserId();
        Date date = new Date();
        CityReceivingInformation cityReceivingInformation = cityReceivingInformationMapper.selectById(id);
        BeanUtils.copyProperties(receivingInformationRequest, cityReceivingInformation);
        cityReceivingInformation.setUserId(userId);
        cityReceivingInformation.setUpdateTime(date);
        iReceivingInformationService.updateById(cityReceivingInformation);
        System.out.println("1212");
    }

    @Override
    public List<ReceivingInformationResponse> getLastTen(Integer num) {
        String userId = JwtUtil.getUserId();
        List<ReceivingInformationResponse> receivingInformationResponses;
        QueryWrapper<ReceivingInformation> receivingInformationQueryWrapper = new QueryWrapper<>();
        receivingInformationQueryWrapper.eq("user_id", userId);
        receivingInformationQueryWrapper.orderByDesc("update_time");
        if (num != 0) {
            receivingInformationQueryWrapper.last("limit " + num);
        }
        List<ReceivingInformation> receivingInformationList = receivingInformationMapper.selectList(receivingInformationQueryWrapper);
        receivingInformationResponses = BeanUtil.copyProperties(receivingInformationList, ReceivingInformationResponse.class);
//        receivingInformationResponses.forEach(receivingInformationResponse->receivingInformationResponse.setPhoneNum(phoneDispose(receivingInformationResponse.getPhoneCode(),receivingInformationResponse.getPhoneNum())));
        return receivingInformationResponses;
    }

    @Override
    public List<ReceivingInformationResponse> getLastTenAddress(Integer num, Integer page, Integer size) {
        String userId = JwtUtil.getUserId();
        List<ReceivingInformationResponse> receivingInformationResponses;
        QueryWrapper<CityReceivingInformation> cityReceivingInformationQueryWrapper = new QueryWrapper<>();
        cityReceivingInformationQueryWrapper.eq("user_id", userId);
        cityReceivingInformationQueryWrapper.orderByDesc("update_time");
        List<CityReceivingInformation> cityReceivingInformations = new ArrayList<>();
        if (ObjectUtils.isEmpty(page) && ObjectUtils.isEmpty(size)) {
            cityReceivingInformationQueryWrapper.last("limit " + num);
            cityReceivingInformations = iReceivingInformationService.selectList(cityReceivingInformationQueryWrapper);
        } else {
            Page<CityReceivingInformation> cityReceivingInformationPage = new Page<>(page, size);
            IPage<CityReceivingInformation> cityReceivingInformationIPage = iReceivingInformationService.selectPage(cityReceivingInformationPage, cityReceivingInformationQueryWrapper);
            cityReceivingInformations = cityReceivingInformationIPage.getRecords();
        }
        receivingInformationResponses = BeanUtil.copyProperties(cityReceivingInformations, ReceivingInformationResponse.class);
        return receivingInformationResponses;
    }

    @Override
//    @CacheEvict(value = "CITY::RECEIVING_INFORMATION", key = "#userId")
    public void delete(String id, String userId) {
        cityReceivingInformationMapper.deleteById(id);
    }

    @Override
    @CacheEvict(value = "RESCUE::RECEIVING_INFORMATION", key = "#userId")
    public void deleteRescue(String id, String userId) {
        receivingInformationMapper.deleteById(id);
    }

    @Override
    public Long getTotal() {
        String userId = JwtUtil.getUserId();
        QueryWrapper<CityReceivingInformation> cityReceivingInformationQueryWrapper = new QueryWrapper<>();
        cityReceivingInformationQueryWrapper.eq("user_id", userId);
        return cityReceivingInformationMapper.selectCount(cityReceivingInformationQueryWrapper);
    }

    @Override
    public int insert(CityReceivingInformation entity) {
        //加密
        String doorplate = entity.getDoorplate();
        String phoneNum = entity.getPhoneNum();
        if (!ObjectUtils.isEmpty(doorplate)) {
            String encryptDoorplate = phoneEncoderUtil.encryptString(doorplate);
            entity.setDoorplate(encryptDoorplate);
        }
        if (!ObjectUtils.isEmpty(phoneNum)) {
            String encryptPhoneNum = phoneEncoderUtil.encryptString(phoneNum);
            entity.setPhoneNum(encryptPhoneNum);
        }
        return cityReceivingInformationMapper.insert(entity);
    }

    @Override
    public int updateById(CityReceivingInformation entity) {
        //加密
        String doorplate = entity.getDoorplate();
        String phoneNum = entity.getPhoneNum();
        if (!ObjectUtils.isEmpty(doorplate)) {
            String encryptDoorplate = phoneEncoderUtil.encryptString(doorplate);
            entity.setDoorplate(encryptDoorplate);
        }
        if (!ObjectUtils.isEmpty(phoneNum)) {
            String encryptPhoneNum = phoneEncoderUtil.encryptString(phoneNum);
            entity.setPhoneNum(encryptPhoneNum);
        }
        return cityReceivingInformationMapper.updateById(entity);
    }

    @Override
    public List<CityReceivingInformation> selectList(Wrapper<CityReceivingInformation> queryWrapper) {
        List<CityReceivingInformation> cityReceivingInformations = cityReceivingInformationMapper.selectList(queryWrapper);
        cityReceivingInformations.forEach(cityReceivingInformation -> {
            String doorplate = cityReceivingInformation.getDoorplate();
            doorplate = phoneEncoderUtil.decryptString(doorplate);
            cityReceivingInformation.setDoorplate(doorplate);

            String phoneNum = cityReceivingInformation.getPhoneNum();
            phoneNum = phoneEncoderUtil.decryptString(phoneNum);
            cityReceivingInformation.setPhoneNum(phoneNum);
        });
        return cityReceivingInformations;
    }

    @Override
    public IPage<CityReceivingInformation> selectPage(Page<CityReceivingInformation> page, Wrapper<CityReceivingInformation> queryWrapper) {
        IPage<CityReceivingInformation> cityReceivingInformationIPage = cityReceivingInformationMapper.selectPage(page, queryWrapper);
        List<CityReceivingInformation> cityReceivingInformations = cityReceivingInformationIPage.getRecords();
        cityReceivingInformations.forEach(cityReceivingInformation -> {
            String doorplate = cityReceivingInformation.getDoorplate();
            doorplate = phoneEncoderUtil.decryptString(doorplate);
            cityReceivingInformation.setDoorplate(doorplate);
            String phoneNum = cityReceivingInformation.getPhoneNum();
            phoneNum = phoneEncoderUtil.decryptString(phoneNum);
            cityReceivingInformation.setPhoneNum(phoneNum);
        });
        return cityReceivingInformationIPage;
    }

    @Override
    public ReceivingInformation getPhoneNum(String id) {
        ReceivingInformation receivingInformation = receivingInformationMapper.selectById(id);
        if (receivingInformation != null && StringUtils.isNotBlank(receivingInformation.getPhoneNum())) {
            receivingInformation.setPhoneNum(phoneEncoderUtil.decryptString(receivingInformation.getPhoneNum()));
        }
        return receivingInformation;
    }

    private String phoneDispose(String phoneCode, String phoneNum) {
        if (!ObjectUtils.isEmpty(phoneCode) && !ObjectUtils.isEmpty(phoneNum) && !phoneNum.matches(PHONE_VERIFY)) {
            return phoneCode + "-" + phoneNum;
        }
        if (ObjectUtils.isEmpty(phoneCode) && !ObjectUtils.isEmpty(phoneNum) && phoneNum.matches(PHONE_VERIFY)) {
            return PhoneDesensitizationUtil.phoneDesensitization(phoneNum);
        }
        return null;
    }
}
